# 通过OCR识别技术识别图片验证码
import base64
import re
import time
import ddddocr
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By

# 1、普通验证码识别
ocr = ddddocr.DdddOcr()
with open('code.png', 'rb') as f:
    image = f.read()
res = ocr.classification(image)
print(res)

#2、 滑块验证码
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get('https://www.kgcaptcha.com/demo/content?t=1')
driver.find_element(By.LINK_TEXT, '弹出式').click()
driver.find_element(By.ID, 'captchaButton').click()
# 获取验证码背景图
bg_pic_style = driver.find_element(By.ID, 'KgBasemap').get_attribute('style')
pattern = re.compile('url\("(.*?)"\)')
# 获取验证码背景图base64编码的数据
bg_src_data = pattern.findall(bg_pic_style)[0]
# base64数据进行解码
bg_src_content = bg_src_data.split(',')[1]
bg_src_data = base64.b64decode(bg_src_content.encode())

# 获取滑块图
slider_pic_data = driver.find_element(By.XPATH, '//*[@id="KgBasemap"]/img[1]').get_attribute('src')
slider_src_content = slider_pic_data.split(',')[1]
# 获取滑块图base64编码的数据
slider_pic_data = base64.b64decode(slider_src_content.encode())
 # 使用ddddocr识别验证码背景图缺口
det = ddddocr.DdddOcr(det=False, ocr=False)
# ` 是使用 `ddddocr` 库中的 `slide_match()` 方法进行验证码背景图缺口的识别和匹配。参数解释：
# - `slider_pic_data`：滑块图的数据，经过base64解码后的图像数据。
# - `bg_src_data`：验证码背景图的数据，经过base64解码后的图像数据。
# - `simple_target=True`：可选参数，表示使用简单的目标匹配方式。
res = det.slide_match(slider_pic_data, bg_src_data, simple_target=True)
# 在代码中，`res` 变量用于接收 `slide_match()` 方法的返回结果。
# print(f'{res}')
distance = res['target'][0]

def get_move_track(distance):
    """
    获取滑动轨迹
    不能直接从开始点直接滑动到终止点（有些网站会判定为脚本操作）
    根据滑动距离生成滑动轨迹，开始慢->中间快->最后慢
    :param distance:滑动距离
    :return:滑动轨迹列表
    """
    remain_distance = distance
    track_list = []
    while remain_distance > 0:
        ratio = (distance - remain_distance) / distance
        if ratio < 0.1:
            span = 4
        elif ratio < 0.9:
            span = 16
        else:
            span = 2
        track_list.append(span)
        remain_distance -= span
    return track_list

# 使用selenium Actionchains进行滑动
slide_button_element = driver.find_element(By.XPATH, '//*[@id="KgSlide"]/div[3]')
ActionChains(driver).click_and_hold(slide_button_element).perform()
time.sleep(0.5)

for i in get_move_track(distance):
    time.sleep(0.01)
    ActionChains(driver).move_by_offset(i, 0).perform()
ActionChains(driver).release(on_element=slide_button_element).perform()

time.sleep(5)
driver.quit()